#include "curtain.h"
#include "help_curtain.h"
#include "usart1.h"
#include "sys.h"
#include "led.h"
#include "font.h"
#include "tim5.h"
#include "w25qxx.h"

// 部分光线屏蔽程序
void curtain_test_and_block_some_light(uint8_t min_id,
                                       uint8_t max_id,
                                       uint32_t n_scan,
                                       uint32_t scan_interval_us,
                                       uint16_t *default_scan_list)
{
    uint32_t success_count = 0, error_count = 0, n = 0, t = 0;
    uint16_t tmpResult;
    uint8_t s[6] = {0};

    // 显示模式切换
    led_display_infomation_and_wait_once((uint8_t *)str_curtain_01); // 显示屏蔽光线提示语
    if(curtain_online_count(max_id) != (max_id - min_id + 1) * 2)
    {
        led_display_infomation_and_wait_once((uint8_t *)str_curtain_07); // 显示传感器未接好提示语
        return;
    }
    static_display_mode();
    dac1_play_by_index(SND_440HZ, 1); // 提示音
    has_tmp_scan_list = 0;

    for (uint8_t i = min_id; i <= max_id; i++)
    {
        // 初始化显示
        uint8_t ch = i > max_id ? ' ' : '0' + i;
        insert_8x16_to_display_buf(get_ascii_font(ch), i - 1);
        tmp_scan_list[i - 1] = 0x0000;

        // 询问发射光栅是否在线
        s[i - 1] = curtain_is_send_online(i);
        *DisplaybufAddr08(0, i - 1) = s[i - 1] ? 0x3C : 0x00;
        s[i - 1] = NewMsgFlag;
        if (s[i - 1] == 0)
        {
            tmp_scan_list[i - 1] = 0xFFFF;
        }
        Delay_ms(100);

        // 询问接收光栅
        n = n_scan;
        while (n-- && s[i - 1])
        {
            // 扫描 n 次
            t = tim3_read_count();
            tmpResult = default_scan_list ? default_scan_list[i - 1] : 0xFFFF; // 有默认值就使用默认值，借用tmpResult
            tmpResult = curtain_read_light_status(i, tmpResult);
            tmp_scan_list[i - 1] |= NewMsgFlag ? tmpResult : 0xFFFF;
            // 显示扫描结果,有灯的是通的，暗的是不通的
            *DisplaybufAddr16(i - 1, 6) = (~tmp_scan_list[i - 1]);
            *DisplaybufAddr08(15, i - 1) = NewMsgFlag ? 0x3C : 0x00;
            success_count++;
            error_count++;
            error_count -= NewMsgFlag;
            // 显示总次数
            *DisplaybufAddr16(14, 6) = __RBIT(success_count) >> 16;
            // 显示出错次数
            *DisplaybufAddr16(15, 6) = __RBIT(error_count) >> 16;
            // 调整两次扫描时间间隔，200us的粒度，注意是间隔，本身扫描就需要1500us左右
            while ((tim3_read_count() - t) < (scan_interval_us / US_PER_ROW))
            {
            }
        }
        // 处理结果,扫描结果转为扫描列表
        tmp_scan_list[i - 1] = RESULT_2_CMD(tmp_scan_list[i - 1]);
        // 默认不要扫的还是不要扫
        tmp_scan_list[i - 1] &= default_scan_list ? default_scan_list[i - 1] : 0xFFFF;
        // 显示扫描结果,为了显示结果和实时结果显示一致，加上了RBIT,点亮的是要扫描的光线
        *DisplaybufAddr16(i - 1, 6) = __RBIT(tmp_scan_list[i - 1]) >> 16;
        // 计数恢复到0
        success_count = 0;
        error_count = 0;
        // 延时一会儿
        dac1_play_by_index(SND_440HZ, 1); // 提示音
        Delay_ms(500);
    }
    has_tmp_scan_list = 1;
    // 停留5秒
    Delay_ms(5000);
    // 比较结果
    uint8_t i = 0;
    for (i = min_id - 1; i < max_id; i++)
    {
        if (default_scan_list[i] != tmp_scan_list[i])
        {
            break;
        }
    }
    // 查看结果是否一样
    if (i != max_id) // 结果不一样
    {
        uint8_t tmp = HAS_TEMP_SCANLIST;
        flash_write_data(TEMP_SCANLIST_FLAG, &tmp, 1);
        flash_write_data(TEMP_SCANLIST_ADDR, (uint8_t *)tmp_scan_list, max_id * 2);
        has_tmp_scan_list = 1;
        led_display_infomation_and_wait_once((uint8_t *)str_curtain_04);
    }
    else // 结果一样
    {
        uint8_t tmp = NO_TEMP_SCANLIST;
        flash_write_data(TEMP_SCANLIST_FLAG, &tmp, 1);
        led_display_infomation_and_wait_once((uint8_t *)str_curtain_03);
    }
    led_clear_display_buf();
}

// 实时查看光栅实时状态,根据扫描间隔每个扫描一些次数
void curtains_light_status_display(uint8_t max_id,
                                   uint16_t *default_scan_list,
                                   uint16_t one_board_test_times,
                                   uint16_t scan_interval,
                                   uint16_t with_sound)
{
    uint32_t success_count = 0, error_count = 0, tmpResult, test_times = 0;
    uint8_t s[6] = {0}, r[6] = {0}, _s[6] = {0}, _r[6] = {0};
    uint8_t delay_flag = 1;
    led_display_infomation_and_wait_once((uint8_t *)str_curtain_02);
    static_display_mode();
    for (uint8_t i = 1; i <= max_id; i++)
    {
        uint8_t ch = i > max_id ? ' ' : '0' + i;
        insert_8x16_to_display_buf(get_ascii_font(ch), i - 1);
    }

    while (1)
    {
        for (uint16_t i = 1; i <= max_id; i++)
        {
            // 发射桩在线状态查询
            if (curtain_is_send_online(i))
            {
                *DisplaybufAddr08(0, i - 1) = 0x3C;
                s[i - 1] = 1;
                if (_s[i - 1] != s[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _s[i - 1] = s[i - 1];
                }
            }
            else
            {
                *DisplaybufAddr08(0, i - 1) = 0x00;
                // *DisplaybufAddr16(i - 1, 6) = default_scan_list ? CMD_2_RESULT(default_scan_list[i - 1]) : 0xFFFF; // 发射桩不在线，光线显示全断，全亮
                *DisplaybufAddr16(i - 1, 6) = 0x00; // 发射桩不在线，光线显示关闭，全不亮
                s[i - 1] = 0;
                if (_s[i - 1] != s[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _s[i - 1] = s[i - 1];
                }
            }
            // 接收桩在线状态查询
            if (curtain_is_recv_online(i))
            {
                *DisplaybufAddr08(15, i - 1) = 0x3C;
                r[i - 1] = 1;
                if (_r[i - 1] != r[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _r[i - 1] = r[i - 1];
                }
            }
            else
            {
                *DisplaybufAddr08(15, i - 1) = 0x00;
                // *DisplaybufAddr16(i - 1, 6) = default_scan_list ? CMD_2_RESULT(default_scan_list[i - 1]) : 0xFFFF; // 不在线，显示为全不通，全亮
                *DisplaybufAddr16(i - 1, 6) = 0x00; // 不在线，不显示任何光线数据， 全不亮
                r[i - 1] = 0;
                if (_r[i - 1] != r[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _r[i - 1] = r[i - 1];
                }
            }
            // 光线阻断情况查询, 一个传感器要测试one_board_test_times 才会测试下一个传感器
            test_times = one_board_test_times;
            if (s[i - 1] && r[i - 1])
            {
                // 如果delay_flag从来没有被置1, 那么就延时100ms
                delay_flag = 0;

                if (with_sound == 1)
                {
                    dac1_play_digit(i);
                }
                while (test_times--)
                {

                    tim5_start_timer(0);                 // 启动一个计时器
                    *DisplaybufAddr08(14, i - 1) = 0x18; // 显示正在扫描的桩，在数字下有两点
                    tmpResult = default_scan_list ? default_scan_list[i - 1] : 0xFFFF;
                    tmpResult = curtain_read_light_status(i, tmpResult);
                    if (NewMsgFlag)
                    {
                        if ((*DisplaybufAddr16(i - 1, 6) != tmpResult))
                        {
                            if (with_sound == 1)
                            {
                                dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                            }
                        }
                        *DisplaybufAddr16(i - 1, 6) = tmpResult;
                        success_count++;
                    }
                    else
                    {
                        // *DisplaybufAddr16(i - 1, 6) = default_scan_list ? CMD_2_RESULT(default_scan_list[i - 1]) : 0xFFFF;
                        *DisplaybufAddr16(i - 1, 6) = 0x00;
                        error_count++;
                    }
                    // 显示成功次数
                    Display16bit(12, 6, success_count >> 16);
                    Display16bit(13, 6, success_count);
                    // 显示出错次数
                    Display16bit(14, 6, error_count >> 16);
                    Display16bit(15, 6, error_count);
                    // 延时到扫描间隔
                    tim5_wait_timer_reached_us(0, scan_interval);
                }
                *DisplaybufAddr08(14, i - 1) = 0x00; // 清除正在扫描的桩的指示
                *DisplaybufAddr16(i - 1, 6) = 0x00;  // 请除上正在扫描传感器扫描结果
            }
        }
        // 防止没有一对传感器在线，在不断扫描，把更新屏幕时间全挤没了
        if (delay_flag == 1)
        {
            Delay_ms(10);
        }
        delay_flag = 1;
    }
}

void curtains_light_status_display_with_history(uint8_t max_id,
                                                uint16_t *default_scan_list,
                                                uint16_t one_board_test_times,
                                                uint16_t scan_interval,
                                                uint16_t with_sound)
{
    uint32_t success_count = 0, error_count = 0, tmpResult, test_times = 0;
    uint8_t s[6] = {0}, r[6] = {0}, _s[6] = {0}, _r[6] = {0};
    uint16_t status[6] = {0, 0, 0, 0, 0, 0};
    led_display_infomation_and_wait_once((uint8_t *)str_curtain_06);
    static_display_mode();
    for (uint8_t i = 1; i <= max_id; i++)
    {
        uint8_t ch = i > max_id ? ' ' : '0' + i;
        insert_8x16_to_display_buf(get_ascii_font(ch), i - 1);
    }

    while (1)
    {
        for (uint16_t i = 1; i <= max_id; i++)
        {
            // 发射桩在线状态查询
            if (curtain_is_send_online(i))
            {
                *DisplaybufAddr08(0, i - 1) = 0x3C;
                s[i - 1] = 1;
                if (_s[i - 1] != s[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _s[i - 1] = s[i - 1];
                }
            }
            else
            {
                *DisplaybufAddr08(0, i - 1) = 0x00;
                // *DisplaybufAddr16(i - 1, 6) = default_scan_list ? CMD_2_RESULT(default_scan_list[i - 1]) : 0xFFFF; // 发射桩不在线，光线显示全断，全亮
                *DisplaybufAddr16(i - 1, 6) = 0x00; // 发射桩不在线，光线显示关闭，全不亮
                s[i - 1] = 0;
                if (_s[i - 1] != s[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _s[i - 1] = s[i - 1];
                }
            }
            // 接收桩在线状态查询
            if (curtain_is_recv_online(i))
            {
                *DisplaybufAddr08(15, i - 1) = 0x3C;
                r[i - 1] = 1;
                if (_r[i - 1] != r[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _r[i - 1] = r[i - 1];
                }
            }
            else
            {
                *DisplaybufAddr08(15, i - 1) = 0x00;
                // *DisplaybufAddr16(i - 1, 6) = default_scan_list ? CMD_2_RESULT(default_scan_list[i - 1]) : 0xFFFF; // 不在线，显示为全不通，全亮
                *DisplaybufAddr16(i - 1, 6) = 0x00; // 不在线，不显示任何光线数据， 全不亮
                r[i - 1] = 0;
                if (_r[i - 1] != r[i - 1])
                {
                    if (with_sound == 1)
                    {
                        dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                    }
                    _r[i - 1] = r[i - 1];
                }
            }
            // 光线阻断情况查询, 一个传感器要测试one_board_test_times 才会测试下一个传感器
            test_times = one_board_test_times;
            if (s[i - 1] && r[i - 1])
            {
                if (with_sound == 1)
                {
                    dac1_play_digit(i);
                }
                while (test_times--)
                {

                    tim5_start_timer(0);                 // 启动一个计时器
                    *DisplaybufAddr08(14, i - 1) = 0x18; // 显示正在扫描的桩，在数字下有两点
                    tmpResult = default_scan_list ? default_scan_list[i - 1] : 0xFFFF;
                    tmpResult = curtain_read_light_status(i, tmpResult);
                    if (NewMsgFlag)
                    {
                        if ((*DisplaybufAddr16(i - 1, 6) != tmpResult))
                        {
                            if (with_sound == 1)
                            {
                                dac1_play_n_ms_by_index(SND_880HZ, 20, 0);
                            }
                        }
                        status[i - 1] |= tmpResult;
                        *DisplaybufAddr16(i - 1, 6) |= status[i - 1];
                        success_count++;
                    }
                    // 显示成功次数
                    Display16bit(12, 6, success_count >> 16);
                    Display16bit(13, 6, success_count);
                    // 显示出错次数
                    Display16bit(14, 6, error_count >> 16);
                    Display16bit(15, 6, error_count);
                    // 延时到扫描间隔
                    tim5_wait_timer_reached_us(0, scan_interval);
                }
                *DisplaybufAddr08(14, i - 1) = 0x00; // 清除正在扫描的桩的指示
            }
        }
    }
}

void curtains_485_test(uint8_t max_id)
{
    uint32_t total_count = 0;
    uint16_t error_count[20] = {0};
    // 初始化显示
    led_display_infomation_and_wait_once((uint8_t *)str_curtain_05);
    static_display_mode();
    for (uint8_t i = 1; i <= max_id; i++)
    {
        uint8_t ch = i > max_id ? ' ' : '0' + i;
        insert_8x16_to_display_buf(get_ascii_font(ch), i - 1);
    }
    for (uint8_t i = 0; i < 16; i++)
    {
        Display16bit(i, 6, 0x0000);
    }

    while (1)
    {
        for (uint16_t i = 1; i <= max_id; i++)
        {
            // 发射桩在线状态查询
            total_count++;
            if (curtain_is_send_online(i))
            {
                *DisplaybufAddr08(0, i - 1) = 0x3C;
            }
            else
            {
                *DisplaybufAddr08(0, i - 1) = 0x00;
                Display16bit((i - 1) * 2, 6, ++error_count[(i - 1) * 2]);
            }
            // 接收桩在线状态查询
            if (curtain_is_recv_online(i))
            {
                *DisplaybufAddr08(15, i - 1) = 0x3C;
            }
            else
            {
                *DisplaybufAddr08(15, i - 1) = 0x00;
                Display16bit((i - 1) * 2 + 1, 6, ++error_count[(i - 1) * 2 + 1]);
            }
            // 显示总次数
            Display16bit(14, 6, total_count >> 16);
            Display16bit(15, 6, total_count);
        }
    }
}